package com.nts.visionworks.core.mediainfo;

import java.net.URL;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import org.apache.catalina.loader.WebappClassLoader;

/**t
 * MediaInfo 라이브러리를 로드하여 사용할 수 있도록 하는 wrapper로 Spring bean으로 등록하여 사용한다.
 * 라이브러리를 로드하기 위해서는 DLL이 필요하며, DLL의 위치를 설정해야 한다.
 * @author Devcken
 */
@ManagedBean
@RequestScoped
public class MediaInfoWrapper
{
	/**
	 * 
	 */
	private MediaInfoNativeAccess _mediaInfoAccess;
	
	/**
	 * 라이브러리의 상대 경로를 나타낸다.
	 */
	private String _libraryPath;
	
	public MediaInfoWrapper(String libraryPath)
	{
		// 운영체제의 아키텍트를 판별하여 아키텍트에 맞는 경로를 판단한다.
		this._libraryPath = String.format("%s%s", libraryPath, System.getProperty("os.arch").contains("86") ? "x86" : "x64");
	}
	
	/**
	 * DLL을 통해 MediaInfo 라이브러리를 로드한다.
	 * @param session HTTP 세션을 전달한다.
	 */
	public void initialize()
	{
		WebappClassLoader classLoader = (WebappClassLoader)this.getClass().getClassLoader();
		
		//classLoader.findRepositories().length
		
		URL url = classLoader.getResource("/");
		
		String p = url.getPath().replaceAll("WEB-INF/classes/", "");
		
		p = String.format("%s%s", p, this._libraryPath);
		
		// 라이브러리 파일(DLL)의 절대 경로를 구한다.
		//String libraryAbsolutePath = String.format("%s%s", this._session.getServletContext().getRealPath("/"), this._libraryPath);
		// 라이브러리 절대 경로를 전달하여 라이브러리를 로드한다.
		this._mediaInfoAccess = new MediaInfoNativeAccess(p);
		
		MediaInfoNativeAccess.Option_Static("Info_Version");
		MediaInfoNativeAccess.Option_Static("Info_Parameters");
		MediaInfoNativeAccess.Option_Static("Info_Capacities");
		MediaInfoNativeAccess.Option_Static("Info_Codecs");
	}
	
	/**
	 * 라이브러리를 통해 메타정보를 알아보고자 하는 미디어 파일을 개방한다.
	 * @param path 미디어 파일의 절대 경로를 설정한다.
	 * @return 성공 여부가 반환된다.
	 */
	public boolean open(String path)
	{
		return this._mediaInfoAccess.Open(path) > 0;
	}
	
	/**
	 * 개방한 미디어 파일을 닫는다.
	 */
	public void close()
	{
		this._mediaInfoAccess.Close();
	}
	
	/**
	 * 개방된 미디어 파일의 모든 정보를 가져온다.
	 * @return 미디어 파일의 모든 정보를 문자열로 반환한다.
	 */
	public String inform()
	{
		return this._mediaInfoAccess.Inform();
	}
	
	/**
	 * 미디어 파일의 특정 메타정보를 추출한다.
	 * @param streamType 스트림의 유형을 설정한다.
	 * @param streamNumber 스트림 내의 번호를 설정한다.
	 * @param parameterIndex 알아내고자 하는 메타정보(Duration, Width, Height 등)의 index를 설정한다.
	 * @return 미디어 파일의 특정 메타정보가 반환된다.
	 */
	public String get(StreamType streamType, int streamNumber, int parameterIndex)
	{
		return this._mediaInfoAccess.Get(streamType, streamNumber, parameterIndex);
	}
	
	/**
	 * 미디어 파일의 특정 메타정보를 추출한다.
	 * @param streamType 스트림의 유형을 설정한다.
	 * @param streamNumber 스트림 내의 번호를 설정한다.
	 * @param parameter 알아내고자 하는 메타정보(Duration, Width, Height 등)의 명칭을 설정한다.
	 * @return 미디어 파일의 특정 메타정보가 반환된다.
	 */
	public String get(StreamType streamType, int streamNumber, String parameter)
	{
		return this._mediaInfoAccess.Get(streamType, streamNumber, parameter);
	}
	
	/**
	 * 미디어 파일의 특정 메타정보를 추출한다.
	 * @param streamType 스트림의 유형을 설정한다.
	 * @param streamNumber 스트림 내의 번호를 설정한다.
	 * @param parameterIndex 알아내고자 하는 메타정보(Duration, Width, Height 등)의 index를 설정한다.
	 * @param informationType 알아내고자 하는 메타정보의 유형을 설정한다.
	 * @return 미디어 파일의 특정 메타정보가 반환된다.
	 */
	public String get(StreamType streamType, int streamNumber, int parameterIndex, InformationType informationType)
	{
		return this._mediaInfoAccess.Get(streamType, streamNumber, parameterIndex, informationType);
	}
	
	/**
	 * 미디어 파일의 특정 메타정보를 추출한다.
	 * @param streamType 스트림의 유형을 설정한다.
	 * @param streamNumber 스트림 내의 번호를 설정한다.
	 * @param parameter 알아내고자 하는 메타정보(Duration, Width, Height 등)의 명칭을 설정한다.
	 * @param informationType 알아내고자 하는 메타정보의 유형을 설정한다.
	 * @return 미디어 파일의 특정 메타정보가 반환된다.
	 */
	public String get(StreamType streamType, int streamNumber, String parameter, InformationType informationType)
	{
		return this._mediaInfoAccess.Get(streamType, streamNumber, parameter, informationType);
	}
	
	/**
	 * 미디어 파일의 특정 메타정보를 추출한다.
	 * @param streamType 스트림의 유형을 설정한다.
	 * @param streamNumber 스트림 내의 번호를 설정한다.
	 * @param parameter 알아내고자 하는 메타정보(Duration, Width, Height 등)의 명칭을 설정한다.
	 * @param informationType 알아내고자 하는 메타정보의 유형을 설정한다.
	 * @param searchType 어떤 유형의 메타정보를 찾을 지 설정한다.
	 * @return 미디어 파일의 특정 메타정보가 반환된다.
	 */
	public String get(StreamType streamType, int streamNumber, String parameter, InformationType informationType, InformationType searchType)
	{
		return this._mediaInfoAccess.Get(streamType, streamNumber, parameter, informationType, searchType);
	}

	public String getLibraryPath()
	{
		return _libraryPath;
	}
}